<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>深拷贝</title>
</head>

<body>
    <script>
        //最简单的版本
        // function isObject(originValue)
        // {
        //     let type = typeof originValue;

        //     if(originValue!=null&&type==="object")
        //     {
        //         return true;
        //     }

        //     return false;
        // }

        // function deepCopy(originValue)
        // {
        //     if(!isObject(originValue))
        //     {
        //         return originValue;
        //     }

        //     let newObj = {};
        //     for(key in originValue)
        //     {
        //         newObj[key] = deepCopy(originValue[key]);
        //     }

        //     return newObj;
        // }

        // let obj = {name:"cq","age":12,friends:{name:"curry",age:20,height:1.90}};
        // let copy = deepCopy(obj);
        // obj.friends.name = "james";
        // console.log("obj:",obj);
        // console.log("copyobj:",copy);

        // //考虑数组
        //   function isObject(originValue)
        // {
        //     let type = typeof originValue;

        //     if(originValue!=null&&type==="object")
        //     {
        //         return true;
        //     }

        //     return false;
        // }

        // function deepCopy(originValue)
        // {
        //     if(!isObject(originValue))
        //     {
        //         return originValue;
        //     }

        //      //考虑到数组
        //     let newObj = Array.isArray(originValue)?[]:{};
        //     for(key in originValue)
        //     {
        //         newObj[key] = deepCopy(originValue[key]);
        //     }

        //     return newObj;
        // }

        // let obj = {name:"cq","age":12,friends:[{name:"curry",age:20,height:1.90},
        // {name:"james",age:90,height:1.90},
        // {name:"kobe",age:20,height:1.90}]};
        // let copy = deepCopy(obj);
        // obj.friends[0].name = "cq";
        // console.log("obj:",obj);
        // console.log("copyobj:",copy);

        // //考虑一些对象不支持for in 
        // function isObject(originValue)
        // {
        //     let type = typeof originValue;

        //     if(originValue!=null&&(type==="object"||type ==="function"))
        //     {
        //         return true;
        //     }

        //     return false;
        // }

        // function deepCopy(originValue)
        // {
        //     if(!isObject(originValue))
        //     {
        //         return originValue;
        //     }

        //     //考虑不支持for of遍历的对象
        //     //1，set
        //     if(originValue instanceof Set)
        //     {
        //         //创建一个newSet
        //         let newSet = new Set();
        //         //
        //         for(const item of originValue)
        //         {
        //             newSet.add(deepCopy(item));
        //         }
        //        return newSet;
        //     }

        //     //考虑到数组
        //     let newObj = Array.isArray(originValue)?[]:{};
        //     for(const key in originValue)
        //     {
        //         newObj[key] = deepCopy(originValue[key]);
        //     }

        //     //考虑symbol要进行单独的处理
        //     const symbolKeys = Object.getOwnPropertySymbols(originValue);
        //     for(const symbolKey of symbolKeys)
        //     {
        //         newObj[symbolKey.description] = deepCopy(originValue[symbolKey]); 
        //     }

        //     return newObj;
        // }


        // let friends = ["james","curry","kobe","kd"];
        // let set = new Set(friends);

        // let obj = {
        //     name:"cq",
        //     set:set
        // }

        // console.log(obj);
        // // obj.set.delete("james");
        // let copyObj = deepCopy(obj);
        // obj.set.add("alen");
        // console.log(obj);
        // console.log(copyObj);

       //解决循环引用的问题
        //考虑一些对象不支持for in 
        function isObject(originValue)
        {
            let type = typeof originValue;

            if(originValue!=null&&(type==="object"||type ==="function"))
            {
                return true;
            }

            return false;
        }

        function deepCopy(originValue,recordMap = new WeakMap())
        {
            if(!isObject(originValue))
            {
                return originValue;
            }

            //考虑不支持for of遍历的对象
            //1，set
            if(originValue instanceof Set)
            {
                //创建一个newSet
                let newSet = new Set();
                //
                for(const item of originValue)
                {
                    newSet.add(deepCopy(item));
                }
               return newSet;
            }

            //创建对象之前就判断是否创建过originValue
            if(recordMap.has(originValue))
            {
                return recordMap.get(originValue);
            }
            //考虑到数组
            let newObj = Array.isArray(originValue)?[]:{};
            //将创建过的对象记录下来
            recordMap.set(originValue,newObj);
            for(const key in originValue)
            {
                newObj[key] = deepCopy(originValue[key],recordMap);
            }

            //考虑symbol要进行单独的处理
            const symbolKeys = Object.getOwnPropertySymbols(originValue);
            for(const symbolKey of symbolKeys)
            {
                newObj[symbolKey.description] = deepCopy(originValue[symbolKey],recordMap); 
            }

            return newObj;
        }


        let friends = ["james", "curry", "kobe", "kd"];
        let newSet = new Set(friends);
        let obj = {
            name: "cq",
            set: newSet,
            obj:
            {
              friends:friends,
              [Symbol]:"我是symbol对象"
            }
        }

        obj.self = obj;
        console.log(obj);
        // obj.set.delete("james");
        let copyObj = deepCopy(obj);
        console.log(obj);
        console.log(copyObj);


    </script>
</body>

</html>